package com.moweilin.mo_gateway.handlers;

import io.vertx.core.http.*;
import io.vertx.core.streams.Pump;
import io.vertx.core.streams.ReadStream;
import io.vertx.core.streams.WriteStream;

/**
 * Created by moweilin on 2017/2/28.
 */
public class DefaultModuleRequestHandler implements IModuleRequestHandler {
    private HttpClient httpClient;
    public DefaultModuleRequestHandler(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

    @Override
    public void handle(ModuleRequest moduleRequest) {
        HttpServerRequest request = moduleRequest.getRequest();
        final HttpServerResponse serverResponse = request.response();
        Module module = moduleRequest.getModule();
        HttpMethod requestMethod = moduleRequest.getMethod();
        HttpClientRequest clientRequest = httpClient.request(requestMethod,module.getPort(),module.getVirtualHost(),moduleRequest.getRequestURI(), clientResponse -> {
            serverResponse.setChunked(true);
            clientResponse.headers().forEach(entry -> {

                if(!entry.getKey().equalsIgnoreCase("host")) {
                    String value = entry.getValue();
                    serverResponse.putHeader(entry.getKey(),value);
                }
            });
            makePump(clientResponse,serverResponse);
        });

        request.headers().forEach(entry -> {

            if(!entry.getKey().equalsIgnoreCase("host")) {
//                value = host;
                String value = entry.getValue();
                clientRequest.putHeader(entry.getKey(),value);
            }

        });
        inboundHeaderTransform(clientRequest);
        if(HttpMethod.PUT == requestMethod || HttpMethod.POST ==requestMethod || HttpMethod.PATCH == requestMethod){
            clientRequest.setChunked(true);
            makePump(request,clientRequest);
        }else {
            clientRequest.end();
        }
    }



    protected void inboundHeaderTransform(HttpClientRequest request){
//        request.putHeader("Context-Path",context);
    }


    private  <T> void makePump(ReadStream<T> readStream, WriteStream<T> writeStream){
        Pump pump = Pump.pump(readStream,writeStream);
        readStream.endHandler(v->writeStream.end());
        pump.start();
    }
}
